package com.anlogic.sdk.tools.nativetool;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;

import com.anlogic.sdk.tools.IBspTool;
import com.anlogic.sdk.tools.model.DocInfo;
import com.anlogic.sdk.tools.model.DriverInfo;
import com.anlogic.sdk.tools.model.LibraryInfo;
import com.anlogic.sdk.tools.model.OSInfo;
import com.anlogic.sdk.utils.JsonUtils;
import com.anlogic.sdk.utils.StringUtils;
import com.anlogic.sdk.utils.UtilsPlugin;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class JniBspTool implements IBspTool {
	private String chip;
	
	private NativeBspTool nativeBspTool = new NativeBspTool();
	
	private boolean printToConsole = false;
	
	private MessageConsole console;
	
	private MessageConsoleStream stdoutStream;
	
	private static final Color CONSOLE_STDOUT_COLOR = new Color(null, 99, 99, 99);
	
	public JniBspTool() {
		console = UtilsPlugin.getDefault().getMessageConsole("BSP Tool");
		stdoutStream = console.newMessageStream();
		stdoutStream.setColor(CONSOLE_STDOUT_COLOR);
	}
	
	public JniBspTool(String chip) {
		this.chip = chip;
		nativeBspTool.setChip(chip);
		console = UtilsPlugin.getDefault().getMessageConsole("BSP Tool");
		stdoutStream = console.newMessageStream();
		stdoutStream.setColor(CONSOLE_STDOUT_COLOR);
	}
	
	@Override
	public String getChip() {
		return this.chip;
	}
	
	@Override
	public void setChip(String chip) {
		this.chip = chip;
		nativeBspTool.setChip(chip);
	}
	
	public void setPrintToConsole(boolean printToConsole) {
		this.printToConsole = printToConsole;
	}
	
	@Override
	public List<DriverInfo> getDriverList(String mssPath) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getDriverList(mssPath);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<DriverInfo>();
		List<DriverInfo> driverList = new ArrayList<DriverInfo>();
		JsonObject jsonObject = JsonUtils.readJson(result);
		for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
			JsonElement value = entry.getValue();
			DriverInfo driver = JsonUtils.parse(value.toString(), DriverInfo.class);
			driverList.add(driver);
		}
		return driverList;
	}

	@Override
	public DriverInfo getDriver(String mssPath, String name) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getDriver(mssPath, name);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return null;
		DriverInfo driver = JsonUtils.parse(result, DriverInfo.class);
		return driver;
	}
	
	@Override
	public List<LibraryInfo> getLibraryList(String mssPath) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getLibraryList(mssPath);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<LibraryInfo>();
		List<LibraryInfo> libList = new ArrayList<LibraryInfo>();
		JsonObject jsonObject = JsonUtils.readJson(result);
		for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
			JsonElement value = entry.getValue();
			LibraryInfo lib = JsonUtils.parse(value.toString(), LibraryInfo.class);
			libList.add(lib);
		}
		return libList;
	}
	
	@Override
	public LibraryInfo getLibrary(String mssPath, String name) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getLibrary(mssPath, name);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return null;
		LibraryInfo lib = JsonUtils.parse(result, LibraryInfo.class);
		return lib;
	}

	@Override
	public List<String> getOsNames() {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getOsNames();
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public List<String> getDriverNames() {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getDriverNames();
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public List<String> getLibraryNames() {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getLibraryNames();
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public List<String> getOsVersions(String name) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getOsVersions(name);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public List<String> getDriverVersions(String name) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getDriverVersions(name);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public List<String> getLibraryVersions(String name) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getLibraryVersions(name);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}
	
	@Override
	public List<String> getLibDescFromCfgFile(String name) {
		List<String> versList = this.getLibraryVersions(name);
		List<String> descList = new ArrayList<String>();
		for (String ver : versList) {
			descList.add(this.getLibraryFromCfgFile(name, ver).getDesc());
		}
		return descList;
	}
	
	@Override
	public OSInfo getOsFromCfgFile(String name, String version) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getOsFromCfgFile(name, version);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return null;
		OSInfo osInfo = JsonUtils.parse(result, OSInfo.class);
		return osInfo;
	}

	@Override
	public DriverInfo getDriverFromCfgFile(String name, String version) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getDriverFromCfgFile(name, version);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return null;
		DriverInfo driverInfo = JsonUtils.parse(result, DriverInfo.class);
		return driverInfo;
	}

	@Override
	public LibraryInfo getLibraryFromCfgFile(String name, String version) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getLibraryFromCfgFile(name, version);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return null;
		LibraryInfo libInfo = JsonUtils.parse(result, LibraryInfo.class);
		return libInfo;
	}

	@Override
	public String getProcessor(String mssPath) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getProcessor(mssPath);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return "";
		return result;
	}

	@Override
	public OSInfo getOsInfo(String mssPath) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getOsInfo(mssPath);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return null;
		OSInfo osInfo = JsonUtils.parse(result, OSInfo.class);
		return osInfo;
	}

	@Override
	public DocInfo getDocInfo(String mssPath) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getDocInfo(mssPath);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return null;
		DocInfo docInfo = JsonUtils.parse(result, DocInfo.class);
		return docInfo;
	}

	@Override
	public void removeDriver(String mssPath, String name) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.removeDriver(mssPath, name);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void addDriver(String mssPath, String name, String version) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.addDriver(mssPath, name, version);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void setDriverVersion(String mssPath, String name, String version) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.setDriverVersion(mssPath, name, version);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void removeLibrary(String mssPath, String name) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.removeLibrary(mssPath, name);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void addLibrary(String mssPath, String name, String version) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.addLibrary(mssPath, name, version);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void setLibraryVersion(String mssPath, String name, String version) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.setLibraryVersion(mssPath, name, version);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void createDefaultMss(String mssPath, String chip, String proc, String os) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.createDefaultMss(mssPath, chip, proc, os);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void createMssFromHpf(String hpf, String mssPath, String chip, String proc, String os) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.createMssFromHpf(hpf, mssPath, chip, proc, os);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void generteBsp(String hpf, String mssPath, String bspLocation) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.generteBsp(hpf, mssPath, bspLocation);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void regenerateBsp(String mssPath, String bspLocation) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.regenerateBsp(mssPath, bspLocation);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void updateBspHpf(String bspLocation, String hpf) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.updateBspHpf(bspLocation, hpf);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public List<String> getIncludePaths(String bspLocation) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getIncludePaths(bspLocation);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}
	
	@Override
	public List<String> getLinkScripts(String appLocation, String chip, String download) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getLinkScripts(appLocation, chip, download);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public String getChipFromHpf(String hpf) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getChipFromHpf(hpf);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return "";
		return result;
	}

	@Override
	public List<String> getAppNames(String os, String chip, String proc) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getAppNames(os, chip, proc);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}
	
	@Override
	public List<String> getLinuxAppNames(String chip, String proc) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getLinuxAppNames(chip, proc);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}
	
	@Override
	public List<String> getDriverAppNames(String driverName, String os, String chip, String proc) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getDriverAppNames(driverName, os, chip, proc);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public String getAppDesc(String appName) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getAppDesc(appName);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return "";
		return result;
	}

	@Override
	public List<String> getAppLibs(String appName) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getAppLibs(appName);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public List<String> getAppExtraLibs(String mssfile, String appName) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getAppExtraLibs(mssfile, appName);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new ArrayList<String>();
		return StringUtils.convertToList(result);
	}

	@Override
	public Map<String, String> getAppBuildProperties(String appName) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		String result = nativeBspTool.getAppBuildProperties(appName);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
		if (null == result) return new HashMap<String, String>();
		return StringUtils.convertToMap(result);
	}

	@Override
	public void generateApp(String bspPath, String appName, String appLocation) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.generateApp(bspPath, appName, appLocation);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}
	
	@Override
	public void updateAppLinkscript(String bspLocation, String appLocation) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.updateAppLinkscript(bspLocation, appLocation);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}
	
	@Override
	public void processAppMakefile(String bspLocation, String appLocation, String appName) {
		if (printToConsole)
			nativeBspTool.redirectStdoutInit();
		nativeBspTool.processAppMakefile(bspLocation, appLocation, appName);
		if (printToConsole)
			stdoutStream.println(nativeBspTool.redirectStdoutDone());
	}

	@Override
	public void reloadMssfile(String mssfile) {
		// TODO Auto-generated method stub
		
	}
}
